﻿using System;
using System.ComponentModel;
using System.Data;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlServerCe;


namespace SqlCeEditor
{
    public partial class Tools : Form
    {

        private string dbFileName = string.Empty;

        public Tools(string sFilename)
        {
            InitializeComponent();
            if (!string.IsNullOrEmpty(sFilename))
            {
                LoadDatabase(sFilename);
            }
        }

        private void btClose_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }

        private void btSelect_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                LoadDatabase(openFileDialog1.FileName);
            }

        }

        private void LoadDatabase(string fileName)
        {
            lbDatabase.Text = Path.GetFileName(fileName);
            this.Text = string.Concat("Tools - ", fileName);
            dbFileName = fileName;
            edPass.Text = string.Empty;
        }

        private void btCompact_Click(object sender, EventArgs e)
        {
            if (!CheckIfDbExists())
                return;

            try
            {
                SqlCeEngine engine = new SqlCeEngine(string.Format("Data Source = {0};Password = {1}", dbFileName, edPass.Text));
                engine.Compact(null);
                MessageBox.Show("Database compacted", "Done");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:\r\n\r\n" + ex.Message, "Compacting failed!");
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private bool CheckIfDbExists()
        {
            if (string.IsNullOrEmpty(dbFileName))
            {
                MessageBox.Show("No database selected!", "Error");
                return false;
            }

            if (!File.Exists(dbFileName))
            {
                MessageBox.Show("Database file is missing!", "Error");
                return false;
            }

            return CreateBackup();

        }

        private bool CreateBackup()
        {
            string backupfile = Path.ChangeExtension(dbFileName, String.Concat(".001", Path.GetExtension(dbFileName)));
            int i = 1;

            try
            {

                while (File.Exists(backupfile))
                {
                    i++;
                    backupfile = Path.ChangeExtension(dbFileName, String.Concat(".", i.ToString("000"), Path.GetExtension(dbFileName)));
                }

                File.Copy(dbFileName, backupfile);
                this.Cursor = Cursors.WaitCursor;
                
                Application.DoEvents(); // update cursor
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error creating backup:\r\n\r\n" + ex.Message, "Error creating backup");
                return false;
            }
        }



        private void btRepair_Click(object sender, EventArgs e)
        {
            if (!CheckIfDbExists())
                return;

            try
            {
                SqlCeEngine engine = new SqlCeEngine(string.Format("Data Source = {0};Password = {1}", dbFileName, edPass.Text));
                engine.Repair(null, RepairOption.RecoverCorruptedRows);
                engine.Repair(null, RepairOption.DeleteCorruptedRows);
                MessageBox.Show("Repair finished", "Done");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:\r\n\r\n" + ex.Message, "Repairing failed!");
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }

        }

        private void btShrink_Click(object sender, EventArgs e)
        {
            if (!CheckIfDbExists())
                return;

            try
            {
                SqlCeEngine engine = new SqlCeEngine(string.Format("Data Source = {0};Password = {1}", dbFileName, edPass.Text));
                engine.Shrink();
                MessageBox.Show("Shrinking finished", "Done");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:\r\n\r\n" + ex.Message, "Shrinking failed!");
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void btUpgrade_Click(object sender, EventArgs e)
        {

            if (!CheckIfDbExists())
                return;
            try
            {
                SqlCeEngine engine = new SqlCeEngine(string.Format("Data Source = {0};Password = {1}", dbFileName, edPass.Text));

                engine.Upgrade();

                MessageBox.Show("Upgrading finished", "Done");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:\r\n\r\n" + ex.Message, "Upgrading failed!");
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void btVerify_Click(object sender, EventArgs e)
        {
            if (!CheckIfDbExists())
                return;
            try
            {
                SqlCeEngine engine = new SqlCeEngine(string.Format("Data Source = {0};Password = {1}", dbFileName, edPass.Text));

                if (engine.Verify())
                    MessageBox.Show("No corruption detected", "Done");
                else MessageBox.Show("Database is corrupted!\r\n\r\nIn case of encrypted databases,\r\nthis may also indicate wrong password", "Done");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:\r\n\r\n" + ex.Message, "Verifying failed!");
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

    }
}
